home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / liboctave / cmd-hist.cc < prev    next >
Text File  |  1997-03-07  |  7KB  |  430 lines

  1. /*
  2.  
  3. Copyright (C) 1996 John W. Eaton
  4.  
  5. This file is part of Octave.
  6.  
  7. Octave is free software; you can redistribute it and/or modify it
  8. under the terms of the GNU General Public License as published by the
  9. Free Software Foundation; either version 2, or (at your option) any
  10. later version.
  11.  
  12. Octave is distributed in the hope that it will be useful, but WITHOUT
  13. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with Octave; see the file COPYING.  If not, write to the Free
  19. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. */
  22.  
  23. /* Modified by Klaus Gebhardt */
  24.  
  25. #ifdef HAVE_CONFIG_H
  26. #include <config.h>
  27. #endif
  28.  
  29. #include <cstring>
  30.  
  31. #include <strstream.h>
  32.  
  33. #ifdef HAVE_FCNTL_H
  34. #include <fcntl.h>
  35. #endif
  36.  
  37. #ifdef HAVE_UNISTD_H
  38. #ifdef HAVE_SYS_TYPES_H
  39. #include <sys/types.h>
  40. #endif
  41. #include <unistd.h>
  42. #endif
  43.  
  44. #include <readline/history.h>
  45.  
  46. #include "file-ops.h"
  47. #include "lo-error.h"
  48. #include "cmd-hist.h"
  49.  
  50. bool command_history::initialized = false;
  51.  
  52. command_history::command_history (const string& f, int n)
  53. {
  54.   if (initialized)
  55.     error ("only one history object can be active at once");
  56.   else
  57.     {
  58.       ignoring_additions = false;
  59.  
  60.       lines_in_file = 0;
  61.       lines_this_session = 0;
  62.  
  63.       xsize = -1;
  64.  
  65.       if (! f.empty ())
  66.     {
  67.       xfile = f;
  68.  
  69.       ::read_history (f.c_str ());
  70.  
  71.       lines_in_file = where ();
  72.  
  73.       ::using_history ();
  74.     }
  75.  
  76.       if (n > 0)
  77.     xsize = n;
  78.  
  79.       initialized = true;
  80.     }
  81. }
  82.  
  83. void
  84. command_history::set_file (const string& f)
  85. {
  86.   xfile = f;
  87. }
  88.  
  89. string
  90. command_history::file (void)
  91. {
  92.   return xfile;
  93. }
  94.  
  95. void
  96. command_history::set_size (int n)
  97. {
  98.   xsize = n;
  99. }
  100.  
  101. int
  102. command_history::size (void)
  103. {
  104.   return xsize;
  105. }
  106.  
  107. void
  108. command_history::ignore_entries (bool flag)
  109. {
  110.   ignoring_additions = flag;
  111. }
  112.  
  113. bool
  114. command_history::ignoring_entries (void)
  115. {
  116.   return ignoring_additions;
  117. }
  118.  
  119. void
  120. command_history::add (const string& s)
  121. {
  122.   if (! ignoring_entries ())
  123.     {
  124.       if (s.empty () ||
  125.       (s.length () == 1 && (s[0] == '\r' || s[0] == '\n' || s[0] == '')))
  126.     return;
  127.  
  128.       string t = s;
  129.       int l = t.length ();
  130.       char c = t[l-2];
  131.       if (c == '\n' || c == '\r' || c == '')
  132.     {
  133.       t.resize (l - 1);
  134.       t[l-2] = '\n';
  135.       if (l == 2)  return;
  136.     }
  137.  
  138.       ::add_history (t.c_str ());
  139.       lines_this_session++;
  140.     }
  141. }
  142.  
  143. void
  144. command_history::remove (int n)
  145. {
  146.   HIST_ENTRY *discard = ::remove_history (n);
  147.  
  148.   if (discard)
  149.     {
  150.       if (discard->line)
  151.     ::free (discard->line);
  152.  
  153.       ::free (discard);
  154.     }
  155. }
  156.  
  157. int
  158. command_history::where (void)
  159. {
  160.   return ::where_history ();
  161. }
  162.  
  163. int
  164. command_history::base (void)
  165. {
  166.   return ::history_base;
  167. }
  168.  
  169. int
  170. command_history::current_number (void)
  171. {
  172.   return (xsize > 0) ? base () + where () : -1;
  173. }
  174.  
  175. void
  176. command_history::stifle (int n)
  177. {
  178.   ::stifle_history (n);
  179. }
  180.  
  181. int
  182. command_history::unstifle (void)
  183. {
  184.   return ::unstifle_history ();
  185. }
  186.  
  187. int
  188. command_history::is_stifled (void)
  189. {
  190.   return ::history_is_stifled ();
  191. }
  192.  
  193. void
  194. command_history::read (bool must_exist)
  195. {
  196.   read (xfile, must_exist);
  197. }
  198.  
  199. void
  200. command_history::read (const string& f, bool must_exist)
  201. {
  202.   if (! f.empty ())
  203.     {
  204.       int status = ::read_history (f.c_str ());
  205.  
  206.       if (status != 0 && must_exist)
  207.     error (status);
  208.       else
  209.     {
  210.       lines_in_file = where ();
  211.  
  212.       ::using_history ();
  213.     }
  214.     }
  215.   else
  216.     error ("command_history::read: missing file name");
  217. }
  218.  
  219. void
  220. command_history::read_range (int from, int to, bool must_exist)
  221. {
  222.   read_range (xfile, from, to, must_exist);
  223. }
  224.  
  225. void
  226. command_history::read_range (const string& f, int from, int to,
  227.                  bool must_exist)
  228. {
  229.   if (from < 0)
  230.     from = lines_in_file;
  231.  
  232.   if (! f.empty ())
  233.     {
  234.       int status = ::read_history_range (f.c_str (), from, to);
  235.  
  236.       if (status != 0 && must_exist)
  237.     error (status);
  238.       else
  239.     {
  240.       lines_in_file = where ();
  241.  
  242.       ::using_history ();
  243.     }
  244.     }
  245.   else
  246.     error ("command_history::read_range: missing file name");
  247. }
  248.  
  249. void
  250. command_history::write (const string& f_arg)
  251. {
  252.   string f = f_arg;
  253.  
  254.   if (f.empty ())
  255.     f = xfile;
  256.  
  257.   if (! f.empty ())
  258.     {
  259.       int status = ::write_history (f.c_str ());
  260.  
  261.       if (status != 0)
  262.     error (status);
  263.     }
  264.   else
  265.     error ("command_history::write: missing file name");
  266. }
  267.  
  268. void
  269. command_history::append (const string& f_arg)
  270. {
  271.   if (lines_this_session)
  272.     {
  273.       if (lines_this_session < where ())
  274.     {
  275.       // Create file if it doesn't already exist.
  276.  
  277.       string f = f_arg;
  278.  
  279.       if (f.empty ())
  280.         f = xfile;
  281.  
  282.       if (! f.empty ())
  283.         {
  284.           file_stat fs (f);
  285.  
  286.           if (! fs)
  287.         {
  288.           int tem;
  289.  
  290.           tem = open (f.c_str (), O_CREAT, 0666);
  291.           close (tem);
  292.         }
  293.  
  294.           int status = ::append_history (lines_this_session, f.c_str ());
  295.  
  296.           if (status != 0)
  297.         error (status);
  298.           else
  299.         lines_in_file += lines_this_session;
  300.  
  301.           lines_this_session = 0;
  302.         }
  303.       else
  304.         error ("comman_history::append: missing file name");
  305.     }
  306.     }
  307. }
  308.  
  309. void
  310. command_history::truncate_file (const string& f_arg, int n)
  311. {
  312.   string f = f_arg;
  313.  
  314.   if (f.empty ())
  315.     f = xfile;
  316.  
  317.   if (! f.empty ())
  318.     ::history_truncate_file (f.c_str (), n);
  319.   else
  320.     error ("command_history::truncate_file: missing file name");
  321. }
  322.  
  323. string_vector
  324. command_history::list (int limit, int number_lines)
  325. {
  326.   string_vector retval;
  327.  
  328.   if (limit)
  329.     {
  330.       HIST_ENTRY **hlist = ::history_list ();
  331.  
  332.       if (hlist)
  333.     {
  334.       int end = 0;
  335.       while (hlist[end])
  336.         end++;
  337.  
  338.       int beg = (limit < 0 || end < limit) ? 0 : (end - limit);
  339.  
  340.       retval.resize (end - beg);
  341.  
  342.       int k = 0;
  343.       for (int i = beg; i < end; i++)
  344.         {
  345.           ostrstream output_buf;
  346.  
  347.           if (number_lines)
  348.         output_buf.form ("%5d%c", i + ::history_base,
  349.                  hlist[i]->data ? '*' : ' '); 
  350.  
  351.           output_buf << hlist[i]->line << ends;
  352.  
  353.           const char *tmp = output_buf.str ();
  354.  
  355.           retval[k++] = tmp;
  356.  
  357.           delete [] tmp;  
  358.         }
  359.     }
  360.     }
  361.  
  362.   return retval;
  363. }
  364.  
  365. string
  366. command_history::get_entry (int n)
  367. {
  368.   string retval;
  369.  
  370.   HIST_ENTRY *entry = ::history_get (::history_base + n);
  371.  
  372.   if (entry && entry->line)
  373.     retval = entry->line;
  374.  
  375.   return retval;
  376. }
  377.  
  378. void
  379. command_history::replace_entry (int which, const string& line)
  380. {
  381.   HIST_ENTRY *discard = ::replace_history_entry (which, line.c_str (), 0);
  382.  
  383.   if (discard)
  384.     {
  385.       if (discard->line)
  386.     ::free (discard->line);
  387.  
  388.       ::free (discard);
  389.     }
  390. }
  391.  
  392. void
  393. command_history::clean_up_and_save (const string& f_arg, int n)
  394. {
  395.   string f = f_arg;
  396.  
  397.   if (f.empty ())
  398.     f = xfile;
  399.  
  400.   if (! f.empty ())
  401.     {
  402.       if (n < 0)
  403.     n = xsize;
  404.  
  405.       stifle (n);
  406.  
  407.       ::write_history (f.c_str ());
  408.     }
  409.   else
  410.     error ("command_history::clean_up_and_save: missing file name");
  411. }
  412.  
  413. void
  414. command_history::error (int err_num)
  415. {
  416.   (*current_liboctave_error_handler) ("%s", strerror (err_num));
  417. }
  418.  
  419. void
  420. command_history::error (const string& s)
  421. {
  422.   (*current_liboctave_error_handler) ("%s", s.c_str ());
  423. }
  424.  
  425. /*
  426. ;;; Local Variables: ***
  427. ;;; mode: C++ ***
  428. ;;; End: ***
  429. */
  430.